/* Pic file routines */

#include "global.h"
#include "pic.h"			/* pic resource file ids */
#include "vu-res.h"		/* general resource file ids */

/* PIC file data */
typedef struct {
	VOID *	pfcb ;
	WORD		images ;				/* number of images */
	UINT		index ;				/* current image */
	BOOL		moved_window ;
	BOOL		reload ;
} PIC_DATA ;

LOCAL_D PIC_DATA *			pdata = NULL ;

LOCAL_C VOID LoadPic(VOID) {
	INT						bit ;
	P_RECT					rect = { {0, 0} } ;

	bit = gOpenBit(file.name, pdata->index, WS_BIT_SEG, &rect.br) ;
	SetMainWindowExtent(0, 0, rect.br.x, rect.br.y) ;
	CopytoMainWindow(bit, &rect) ;
	wFree(bit) ;
}

LOCAL_C VOID SaveCurrPic(VOID) {
	TEXT				fname[P_FNAMESIZE] ;
	H_DI_FSEL		fsel = { NULL, H_FILE_NEW_EDITOR | H_FILE_SET_DEFEXT } ;
	INT				ret ;

	uZTStoBCS(fsel.fname = fname, "LOC::M:\\*.PIC") ;

	f_leave( uOpenDialog(NULL) ) ;
	Res_AddDialogItem(H_DIALOG_FSEL, RS_SAVE_AS, &fsel) ;
	ret = Res_RunDialog() ;

	if ( ret ) {
		fsel.fname[fsel.fname[0] + 1] = '\x0' ;
		gSaveBit(&fsel.fname[1], GetMainWid()) ;
	}
}

LOCAL_D H_MENU_DATA	Picmdata[] = {	"Pic File", 3,
												NULL } ;

LOCAL_D TEXT *			Piccmds[] = {	"oOpen",
												"sSave Pic",
												"xExit",
												NULL } ;

#pragma save, ENTER_CALL

LOCAL_C INT PicFileInfo(VOID) {
	/* Return TRUE if an error occurred */
	P_EXTENT			extent ;
	TEXT				str[80] ;
	TEXT *			res_str = NULL ;
	H_DI_TEXT		dialog_txt = { NULL, H_DTEXT_ALIGN_LEFT } ;

	/* Display special info for PIC files:
		Index xx, xx images
		Dimensions: xx x xx pixels
	*/

	GetMainWindowExtent(&extent) ;

	dialog_txt.str = str ;
	ReadResource(RS_PIC_INDEX, &res_str) ;
	p_atos(&dialog_txt.str[1], res_str, pdata->index, pdata->images) ;
	p_free(res_str) ;
	res_str = NULL ;

	dialog_txt.str[0] = p_slen(&dialog_txt.str[1]) ;
	f_leave( uAddDialogItem(H_DIALOG_TEXT, NULL, &dialog_txt) ) ;

	ReadResource(RS_PIC_PIXELS, &res_str) ;
	p_atos(&dialog_txt.str[1], res_str, extent.width, extent.height) ;
	p_free(res_str) ;
	res_str = NULL ;

	dialog_txt.str[0] = p_slen(&dialog_txt.str[1]) ;
	f_leave( uAddDialogItem(H_DIALOG_TEXT, NULL, &dialog_txt) ) ;

	return(E_APP_NONE) ;
}

LOCAL_C INT PicMenuExec(INT index) {
	switch ( index ) {
		case 0 :
			MainDialog() ;
			break ;

		case 1 :
			SaveCurrPic() ;
			break ;

		case 2 :
			Quit() ;
			break ;
		default :
			return(E_APP_NONE) ;
	}
	return(E_APP_NONE) ;
}

LOCAL_C INT PicCleanUp(VOID) {
	if ( pdata != NULL ) {
		if ( pdata->pfcb != NULL ) {
			p_close(pdata->pfcb) ;
			pdata->pfcb = NULL ;
		}

		p_free(pdata) ;
		pdata = NULL ;
	}

	return(E_APP_NONE) ;
}

LOCAL_C INT PicInit(VOID) {
	LONG			numpics_offset = sizeof(P_FSIG) ;

	pdata = f_alloc(sizeof(PIC_DATA)) ;

	/* Read number of pics in file */
	f_open(&pdata->pfcb, file.name, P_FSTREAM | P_FOPEN | P_FRANDOM | P_FSHARE) ;
	f_seek(pdata->pfcb, P_FABS, &numpics_offset) ;
	f_read(pdata->pfcb, &pdata->images, sizeof(WORD)) ;
	p_close(pdata->pfcb) ;
	pdata->pfcb = NULL ;

	pdata->index = 0 ;
	pdata->moved_window = FALSE ;
	pdata->reload = TRUE ;

	return(E_APP_NONE) ;
}

LOCAL_C INT PicUpdate(VOID) {
	TEXT						buf[P_FNAMESIZE] ;
	P_EXTENT					extent ;
	SCROLL_BAR_STATE		barstate ;

	if ( pdata->moved_window || pdata->reload ) {
		if ( pdata->reload ) {
			LoadPic() ;
			pdata->reload = FALSE ;
		}

		/* Filename : xx/xx */
		p_atos(buf, "%s : %d/%d", file.name, pdata->index + 1, pdata->images) ;
		UpdateStatus(buf) ;

		GetMainWindowExtent(&extent) ;

		barstate.start = -extent.tl.x ;
		barstate.size = metrics.disp_size.x ;
		barstate.total = extent.width ;
		UpdateXScroll(&barstate) ;

		barstate.start = -extent.tl.y ;
		barstate.size = metrics.disp_size.y ;
		barstate.total = extent.height ;
		UpdateYScroll(&barstate) ;

		pdata->moved_window = FALSE ;
	}
	return(E_APP_NONE) ;
}

LOCAL_C INT PicPlainKey(WMSG_KEY *pkey) {
	if (	pkey->keycode >= W_KEY_UP &&
			pkey->keycode <= W_KEY_END ) {
		pdata->moved_window = MoveMainWindow(pkey->keycode) ;
	}
	else switch ( pkey->keycode ) {
		case ',' :
			if ( pdata->index > 0 ) {
				pdata->index-- ;
				pdata->reload = TRUE ;
			}
			break ;
		case '.' :
			if ( pdata->index < pdata->images - 1 ) {
				pdata->index++ ;
				pdata->reload = TRUE ;
			}
			break ;
		case '<' :
			if ( pdata->index > 0 ) {
				pdata->index = 0 ;
				pdata->reload = TRUE ;
			}
			break ;
		case '>' :
			if ( pdata->index < pdata->images - 1 ) {
				pdata->index = pdata->images - 1 ;
				pdata->reload = TRUE ;
			}
			break ;
		case 'w' :
		case 's' :
			SaveCurrPic() ;
			break ;
		default :
			break ;
	}
	return(E_APP_NONE) ;
}

#pragma restore

LOCAL_C INT PicRecog(BYTE *buf, UINT buflen) {
	static P_FSIG		pic_header = { "PIC", 'P'+'I'+'C', 0x30, 0x30 } ;

	buflen = MIN(buflen, sizeof(P_FSIG)) ;
	return ( !p_bcmp(buf, buflen, &pic_header, buflen) ) ;
}

GLDEF_C VOID PicDefns(DEFNS *pdefns) {
	pdefns->pfRecognize =		PicRecog ;

	pdefns->pcmds =				Piccmds ;
	pdefns->pmdata =				Picmdata ;
	pdefns->nHelp =				RH_PIC ;
	pdefns->flags = 				STATUS_BAR | SCROLL_X | SCROLL_Y | SUPER ;
	pdefns->style =				G_STY_NORMAL ;

	pdefns->pfCleanUp =			PicCleanUp ;
	pdefns->pfInit =				PicInit ;
	pdefns->pfFileInfo =			PicFileInfo ;
	pdefns->pfUpdate =			PicUpdate ;
	pdefns->pfMenuExec =			PicMenuExec ;
	pdefns->pfPlainKey =			PicPlainKey ;
}
